﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using System.Xml;

using XEvents.Library.Targets;


namespace XEvents.Addin
{
    public partial class TargetDataViewer : Form
    {
        private TargetData data;
        private BindingSource bs;

        public TargetDataViewer()
        {
            InitializeComponent();
            //this.ToolTipText = this.TabText;
        }
        public TargetDataViewer(TargetData td)
        {
            InitializeComponent();
            data = td;
        }

        private void TargetDataViewer_Load(object sender, EventArgs e)
        {
            data.ProgressChanged += new ProgressChangedEventHandler(data_ProgressChanged);
            data.RunWorkerCompleted += new RunWorkerCompletedEventHandler(data_RunWorkerCompleted);
            data.StatusChanged += new LoadStatusChangedEventHandler(data_StatusChanged);
            data.TargetInfoUpdated += new DataTableUpdateEventHandler(data_TargetInfoUpdated);

            button1.Text = "Cancel";
            //this.ToolTipText = this.TabText;
        }

        void data_TargetInfoUpdated(object sender, EventArgs e)
        {
            if (InvokeRequired)
                Invoke(new MethodInvoker(RebindForm));
            else
                RebindForm();
        }

        void RebindForm()
        {
            BindGroupBoxData();
            BindGridView();
        }
        public void SetEventHandlers()
        {
            //this.DockPanel.ActiveDocumentChanged += new System.EventHandler(this.DockPanel_ActiveDocumentChanged);
        }


        void data_StatusChanged(object sender, LoadStatusChangedEventArgs e)
        {
            SetStatus(e);
            //tssl_CurrentStatus.Text = e.CurrentStatus.ToString().Replace("_", " ");
        }

        delegate void SetStatusCallback(LoadStatusChangedEventArgs e);
        delegate void ProgressChangedCallback(ProgressChangedEventArgs e);
        void SetStatus(LoadStatusChangedEventArgs e)
        {
            if (!this.IsDisposed)
            {
                if (!InvokeRequired)
                {
                    if (e.CurrentStatus == LoadStatus.Requesting_Data)
                        tssl_ProgressBar.Style = ProgressBarStyle.Marquee;
                    else
                        tssl_ProgressBar.Style = ProgressBarStyle.Continuous;
                    tssl_CurrentStatus.Text = e.CurrentStatus.ToString().Replace("_", " ");
                }
                else
                    Invoke(new SetStatusCallback(SetStatus), e);
            }
        }

        void data_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            RebindForm();
            button1.Text = "Refresh Target Data From Server";
            button1.Enabled = true;
            tssl_ProgressBar.Value = 100;
        }

        void data_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            ProgressChanged(e);
        }

        void ProgressChanged(ProgressChangedEventArgs e)
        {
            if (!this.IsDisposed)
            {
                if (!InvokeRequired)
                {
                    if (ShouldResetGrid())
                    {
                        bs.RaiseListChangedEvents = true;
                        bs.ResetBindings(false);
                        bs.RaiseListChangedEvents = false;
                    }
                    tssl_ProgressBar.Value = e.ProgressPercentage;
                    System.Diagnostics.Debug.WriteLine(data.TargetInfo.Rows.Count);
                    UpdateStatusStrip();
                }
                else
                    Invoke(new ProgressChangedCallback(ProgressChanged), e);
            }
        }

        private bool ShouldResetGrid()
        {
            int rowcount = ((DataTable)bs.DataSource).Rows.Count;
            if (rowcount <= 1000 && rowcount % 250 == 0)
                return true;
            if (rowcount > 1000 && rowcount <= 10000 && rowcount % 1000 == 0)
                return true;
            if (rowcount > 10000 && rowcount <= 100000 && rowcount % 5000 == 0)
                return true;
            if (rowcount > 100000 && rowcount % 10000 == 0)
                return true;
            return false;
        }

        private void BindGridView()
        {
            if (InvokeRequired)
            {
                Invoke(new MethodInvoker(BindGridView));
            }
            else
            {
                bs = new BindingSource();
                bs.DataSource = data.TargetInfo;
                bs.RaiseListChangedEvents = false;

                dataGridView1.DataSource = bs;

                foreach (DataGridViewColumn col in dataGridView1.Columns)
                {
                    col.AutoSizeMode = DataGridViewAutoSizeColumnMode.None;
                    col.Resizable = DataGridViewTriState.True;
                }
                UpdateStatusStrip();
            }
        }

        private void UpdateStatusStrip()
        {
            if (InvokeRequired)
            {
                Invoke(new MethodInvoker(UpdateStatusStrip));
            }
            else
            {
                if (dataGridView1.SelectedCells.Count > 0)
                {
                    int row = dataGridView1.SelectedCells[0].RowIndex + 1;
                    int col = dataGridView1.SelectedCells[0].ColumnIndex + 1;

                    tssl_RowSelected.Text = "Ln " + row.ToString() + ", Col " + col.ToString();
                }
                tssl_RowCount.Text = "Rows: " + dataGridView1.Rows.Count.ToString();
            }
        }

        private void BindGroupBoxData()
        {
            if (InvokeRequired)
            {
                Invoke(new MethodInvoker(BindGroupBoxData));
            }
            else
            {
                if (data is Target_RingBuffer)
                {
                    Target_RingBuffer tr = ((Target_RingBuffer)data);
                    grp_RingBuffer.BringToFront();
                    txt_DroppedCount.Text = tr.DroppedCount.ToString();
                    txt_EventCount.Text = tr.EventCount.ToString();
                    txt_EventsPerSec.Text = tr.EventsPerSecond.ToString();
                    txt_MemoryUsed.Text = tr.MemoryUsed.ToString();
                    txt_ProcessTime.Text = tr.ProcessingTime.ToString();
                    txt_TotalEvents.Text = tr.TotalEventsProcessed.ToString();
                }
                else if (data is Target_File)
                {
                    Target_File tf = ((Target_File)data);
                    grp_FileTarget.BringToFront();
                    txt_BuffersDropped.Text = tf.BuffersDropped.ToString();
                    txt_BuffersLogged.Text = tf.BuffersLogged.ToString();
                    txt_Truncated.Text = tf.Truncated.ToString();
                }
                else if (data is Target_PairMatching)
                {
                    Target_PairMatching tp = ((Target_PairMatching)data);
                    grp_PairMatching.BringToFront();

                    txt_PM_DroppedCount.Text = tp.MemoryPressureDroppedCount.ToString();
                    txt_PM_MatchedCount.Text = tp.MatchedCount.ToString();
                    txt_PM_OrphanedCount.Text = tp.OrphanCount.ToString();
                    txt_PM_Truncated.Text = tp.Truncated.ToString();
                }
                else if (data is Target_Counter)
                {
                    Target_Counter tc = ((Target_Counter)data);
                    //BindCounter((Target_Counter)td);
                }
            }
        }

        private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
            if (e != null)
            {
                if (e.RowIndex > -1)
                {
                    this.txt_SelectedColumn.Text = ((DataGridView)sender).Rows[e.RowIndex].Cells[e.ColumnIndex].Value.ToString().Replace('\n'.ToString(), "\r\n");
                }
            }
        }

        private void dataGridView1_SelectionChanged(object sender, EventArgs e)
        {
            UpdateStatusStrip();
            /*
            if (((DataGridView)sender).SelectedRows.Count > 0)
            {
                foreach (DataGridViewCell dgvc in ((DataGridView)sender).SelectedRows[0].Cells)
                {
                    if (dgvc.OwningColumn.Name == "sql_text" || dgvc.OwningColumn.Name == "xml_report")
                        this.txt_SelectedColumn.Text = dgvc.Value.ToString().Replace('\n'.ToString(), "\r\n");
                }

            }*/
        }

        private void button1_Click(object sender, EventArgs e)
        {

            switch (button1.Text)
            {
                case "Refresh Target Data From Server":
                    button1.Text = "Cancel";
                    data.Refresh();
                    break;
                case "Cancel":
                    data.CancelAsync();
                    button1.Enabled = false;
                    break;
            }
            BindGroupBoxData();
            BindGridView();
        }

        public void SessionStopped()
        {
            data.CancelAsync();
            this.button1.Enabled = false;
        }

        private void sToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //ColumnSelectorForm csf = new ColumnSelectorForm(this.dataGridView1);
            //csf.ShowDialog();
            //csf.Show(this.DockPanel, DockState.Float);
        }

        private void TargetDataViewer_FormClosing(object sender, FormClosingEventArgs e)
        {
            data.CancelAsync();
        }

    }
}